#include <string.h>

#include "wm_hal.h"
#include "core_804.h"
#include "wm_crypto_hard.h"


//
// CRYPTION模块包含各种各样的加解密算法、CRC、MD5校验生成算法, 同一时刻只能运行某个子功能(当前使用TRNG真随机数模块, 就不能于AES、MD5、CRC等操作)
// 这里会给出所有子模块的API, 如果API里标记返回值信息, 返回值非0表示操作成功, 才能调用该模块的后续函数(如TRNG随机数模块)
//
// 以md5为例, tls_crypto_md5_init()返回非负, CRYPTION模块被锁定为MD5模式, 可使用tls_crypto_md5_update()计算MD5值, 最后使用tls_crypto_md5_final()
// 获取计算结果(最后会释放模块, 可用于其它场合如CRC、AES等).
//
// 注意, TRNG每次都要调用xxx_init(), xxx_bytes(), xxx_stop()函数，产生随机数,                         要判断xxx_init要判断返回值
//       AES、DES、3DES模块, 首次调用xxx_init, 以后只要调用xxx_encrypt_decrypt()函数即可              要判断函数返回值
//       CRC、MD5、SHA1模块，每次都要调用xxx_init(), xxx_update(), xxx_final()函数校验值              要判断xxx_init返回值   
//
// 修改官方提供的API, 对各个加解密模块的API添加锁、解锁操作（参考HAL库实现）, 本文件里有各个模块的demo代码, 由官方提供, 没有对下面函数的返回值进行判断, 自己判断即可
//
//
// TRNG真随机数模块
// tls_crypto_random_init()           返回值小于0, 表示被其他占用(如CRC、MD5、AES等)
// tls_crypto_random_bytes()          if(tls_crypto_random_init() >= 0){tls_crypto_random_bytes();tls_crypto_random_bytes(); tls_crypto_random_stop();}
// tls_crypto_random_stop()      
//
// tls_crypto_rc4_init()
// tls_crypto_rc4()                   返回小于0, 表示被其它模块占用, 返回0表示操作成功, 返回值大于0表示加解密后的数据长度
// 
// 
// tls_crypto_aes_init();
// tls_crypto_aes_encrypt_decrypt();  返回小于0, 表示被其它模块占用, 返回0表示操作成功, 返回值大于0表示加解密后的数据长度
//
//
// tls_crypto_des_init();
// tls_crypto_des_encrypt_decrypt();  返回小于0, 表示被其它模块占用, 返回0表示操作成功, 返回值大于0表示加解密后的数据长度
//
//
// tls_crypto_3des_init();
// tls_crypto_3des_encrypt_decrypt(); 返回小于0, 表示被其它模块占用, 返回0表示操作成功, 返回值大于0表示加解密后的数据长度
//
//
// tls_crypto_crc_init();
// tls_crypto_crc_update();           返回小于0, 表示被其它模块占用, 返回0表示操作成功, 返回值大于0表示加解密后的数据长度
// tls_crypto_crc_final();            if(tls_crypto_crc_init() >= 0){tls_crypto_crc_update(); tls_crypto_crc_update(); ... tls_crypto_crc_final();}
//
//
// tls_crypto_md5_init();             返回小于0, 表示被其它模块占用, 该函数返回非负, 可以调用MD5的后续函数产生校验信息
// tls_crypto_md5_update();           if(tls_crypto_md5_init()>= 0) {tls_crypto_md5_update(); tls_crypto_md5_update(); ... tls_crypto_md5_final();}
// tls_crypto_md5_final();            
//
//
// tls_crypto_sha1_init();            返回小于0, 表示被其它模块占用, 该函数返回非负, 可以调用SHA1的后续函数
// tls_crypto_sha1_update();          if(tls_crypto_sha1_init()>= 0) {tls_crypto_sha1_update(); tls_crypto_sha1_update(); ... tls_crypto_sha1_final();}
// tls_crypto_sha1_final();
//
//

void RNG_hard_demo(void)
{
	//uint8_t *out = NULL;
	uint16_t i;
	static uint8_t out[1000];
	
	//out = tls_mem_alloc(1000);
	tls_crypto_random_init(0xFDA3C97A, CRYPTO_RNG_SWITCH_16);  // init后要延时一丢丢, 才能拿到随机数
	HAL_Delay(1); 
	
	tls_crypto_random_bytes(out, 30);
	printf("\nRNG out:\n");
	for(i=0; i<30; i++)
	{
		printf("%X ", out[i]);
	}
    printf("\n");

	tls_crypto_random_bytes(out, 20);  // 要第二次开始读, 获取到的数据才是随机的

	printf("RNG out:\n");
	for(i=0; i<20; i++)
	{
		printf("%X ", out[i]);
	}
	printf("\n");
	
	tls_crypto_random_stop();

	//tls_mem_free(out);
}

int rc4_hard_demo(void)
{
	psCipherContext_t ctx;
	//uint8_t *in = NULL;
	//uint8_t *out1 = NULL;
	//uint8_t *out2 = NULL;
	//uint8_t *key = NULL;
	int i;

	tls_crypto_init();
	static uint8_t in[1000];
	static uint8_t out1[1000];
	static uint8_t out2[1000];
	static uint8_t key[16];
	//in = tls_mem_alloc(1000);
	//out1 = tls_mem_alloc(1000);
	//out2 = tls_mem_alloc(1000);
	//key = tls_mem_alloc(16);

	if((in==NULL) || (out1==NULL) || (out2==NULL) || (key==NULL))
	{
		printf("malloc err\n");
		goto OUT;
	}

	for(i=0; i<1000; i++)
	{
		in[i] = rand();
	}

	for(i=0; i<16; i++)
	{
		key[i] = rand();
	}

	memset(out1, 0, 1000);
	memset(out2, 0, 1000);

	if(0 != tls_crypto_rc4_init(&ctx, key, 16))
	{
		printf("rc4 init err\n");
		goto OUT;
	}
	tls_crypto_rc4(&ctx, in, out1, 1000);
	tls_crypto_rc4(&ctx, out1, out2, 1000);

	if(memcmp(in, out2, 1000))
	{
		printf("rc4 test fail\n");
	}
	else
	{
		printf("rc4 test success\n");
	}

OUT:
	//if(in != NULL)
	//	tls_mem_free(in);
	//if(out1 != NULL)
	//	tls_mem_free(out1);
	//if(out2 != NULL)
	//	tls_mem_free(out2);
	//if(key != NULL)
	//	tls_mem_free(key);
	
	return 0;
}


int aes_hard_demo(void)
{
	psCipherContext_t ctx;
	//uint8_t *in = NULL;
	//uint8_t *out1 = NULL;
	//uint8_t *out2 = NULL;
	//uint8_t *key = NULL;
	//uint8_t *iv = NULL;
	int i;

	tls_crypto_init();

    static uint8_t in[1024];
	static uint8_t out1[1024];
	static uint8_t out2[1024];
	static uint8_t key[16];
	static uint8_t iv[16];
	//in = tls_mem_alloc(1024);		//AES 必须是16的整数倍，否则会出错
	//out1 = tls_mem_alloc(1024);
	//out2 = tls_mem_alloc(1024);
	//key = tls_mem_alloc(16);
	//iv = tls_mem_alloc(16);

	if((in==NULL) || (out1==NULL) || (out2==NULL) || (key==NULL) || (iv==NULL))
	{
		printf("malloc err\n");
		goto OUT;
	}

	for(i=0; i<1024; i++)
	{
		in[i] = rand();
	}

	for(i=0; i<16; i++)
	{
		key[i] = rand();
		iv[i] = rand();
	}

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_aes_init(&ctx, iv, key, 16, CRYPTO_MODE_ECB);
	tls_crypto_aes_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_aes_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("aes ecb test fail\n");
	}
	else
	{
		printf("aes ecb test success\n");
	}

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_aes_init(&ctx, iv, key, 16, CRYPTO_MODE_CBC);
	tls_crypto_aes_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_aes_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("aes cbc test fail\n");
	}
	else
	{
		printf("aes cbc test success\n");
	}	

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_aes_init(&ctx, iv, key, 16, CRYPTO_MODE_CTR);
	tls_crypto_aes_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_aes_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("aes ctr test fail\n");
	}
	else
	{
		printf("aes ctr test success\n");
	}		

OUT:
	//if(in != NULL)
	//	tls_mem_free(in);
	//if(out1 != NULL)
	//	tls_mem_free(out1);
	//if(out2 != NULL)
	//	tls_mem_free(out2);
	//if(key != NULL)
	//	tls_mem_free(key);
	//if(iv != NULL)
	//	tls_mem_free(iv);
	
	return 0;
	
}


int des_hard_demo(void)
{
	psCipherContext_t ctx;
	//uint8_t *in = NULL;
	//uint8_t *out1 = NULL;
	//uint8_t *out2 = NULL;
	//uint8_t *key = NULL;
	//uint8_t *iv = NULL;
	int i;

	tls_crypto_init();

    static uint8_t in[1024];
	static uint8_t out1[1024];
	static uint8_t out2[1024];
	static uint8_t key[8];
	static uint8_t iv[8];
	//in = tls_mem_alloc(1024);		
	//out1 = tls_mem_alloc(1024);
	//out2 = tls_mem_alloc(1024);
	//key = tls_mem_alloc(8);
	//iv = tls_mem_alloc(8);

	if((in==NULL) || (out1==NULL) || (out2==NULL) || (key==NULL) || (iv==NULL))
	{
		printf("malloc err\n");
		goto OUT;
	}

	for(i=0; i<1024; i++)
	{
		in[i] = rand();
	}

	for(i=0; i<8; i++)
	{
		key[i] = rand();
		iv[i] = rand();
	}	

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_des_init(&ctx, iv, key, 8, CRYPTO_MODE_ECB);
	tls_crypto_des_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_des_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("des ecb test fail\n");
	}
	else
	{
		printf("des ecb test success\n");
	}	

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_des_init(&ctx, iv, key, 8, CRYPTO_MODE_CBC);
	tls_crypto_des_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_des_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("des cbc test fail\n");
	}
	else
	{
		printf("des cbc test success\n");
	}	

OUT:
	//if(in != NULL)
	//	tls_mem_free(in);
	//if(out1 != NULL)
	//	tls_mem_free(out1);
	//if(out2 != NULL)
	//	tls_mem_free(out2);
	//if(key != NULL)
	//	tls_mem_free(key);
	//if(iv != NULL)
	//	tls_mem_free(iv);
	
	return 0;	

}


int des3_hard_demo(void)
{
	psCipherContext_t ctx;
	//uint8_t *in = NULL;
	//uint8_t *out1 = NULL;
	//uint8_t *out2 = NULL;
	//uint8_t *key = NULL;
	//uint8_t *iv = NULL;
	int i;

	tls_crypto_init();

    static uint8_t in[1024];
	static uint8_t out1[1024];
	static uint8_t out2[1024];
	static uint8_t key[24];
	static uint8_t iv[8];
	//in = tls_mem_alloc(1024);		
	//out1 = tls_mem_alloc(1024);
	//out2 = tls_mem_alloc(1024);
	//key = tls_mem_alloc(24);
	//iv = tls_mem_alloc(8);

	if((in==NULL) || (out1==NULL) || (out2==NULL) || (key==NULL) || (iv==NULL))
	{
		printf("malloc err\n");
		goto OUT;
	}

	for(i=0; i<1024; i++)
	{
		in[i] = rand();
	}

	for(i=0; i<24; i++)
	{
		key[i] = rand();
	}

	for(i=0; i<8; i++)
	{	
		iv[i] = rand();
	}	

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_3des_init(&ctx, iv, key, 24, CRYPTO_MODE_ECB);
	tls_crypto_3des_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_3des_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("3des ecb test fail\n");
	}
	else
	{
		printf("3des ecb test success\n");
	}

	memset(out1, 0, 1024);
	memset(out2, 0, 1024);
	tls_crypto_3des_init(&ctx, iv, key, 24, CRYPTO_MODE_CBC);
	tls_crypto_3des_encrypt_decrypt(&ctx, in, out1, 1024, CRYPTO_WAY_ENCRYPT);
	tls_crypto_3des_encrypt_decrypt(&ctx, out1, out2, 1024, CRYPTO_WAY_DECRYPT);
	if(memcmp(in, out2, 1024))
	{
		printf("3des cbc test fail\n");
	}
	else
	{
		printf("3des cbc test success\n");
	}	

OUT:
	//if(in != NULL)
	//	tls_mem_free(in);
	//if(out1 != NULL)
	//	tls_mem_free(out1);
	//if(out2 != NULL)
	//	tls_mem_free(out2);
	//if(key != NULL)
	//	tls_mem_free(key);
	//if(iv != NULL)
	//	tls_mem_free(iv);
	
	return 0;

}


int crc_hard_demo(void)
{
	uint32_t crckey = 0xFFFFFFFF;
	psCrcContext_t ctx;
	//uint8_t *in = NULL;
	int i;
	uint32_t crcvalue = 0;

	tls_crypto_init();
    static uint8_t in[1024];
	//in = tls_mem_alloc(1024);
	if(in==NULL)
	{
		printf("malloc err\n");
		goto OUT;
	}

	for(i=0; i<1024; i++)
	{
		in[i] = rand();
	}	
	
	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_8, 0);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_8 normal value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_8, INPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_8 INPUT_REFLECT value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_8, OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_8 OUTPUT_REFLECT value:0x%08X\n", crcvalue);	

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_8, INPUT_REFLECT | OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_8 INPUT_REFLECT | OUTPUT_REFLECT value:0x%08X\n", crcvalue); 


	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_MODBUS, 0);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_MODBUS normal value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_MODBUS, INPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_MODBUS INPUT_REFLECT value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_MODBUS, OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_MODBUS OUTPUT_REFLECT value:0x%08X\n", crcvalue); 

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_MODBUS, INPUT_REFLECT | OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_MODBUS INPUT_REFLECT | OUTPUT_REFLECT value:0x%08X\n", crcvalue); 


	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_CCITT, 0);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_CCITT normal value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_CCITT, INPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_CCITT INPUT_REFLECT value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_CCITT, OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_CCITT OUTPUT_REFLECT value:0x%08X\n", crcvalue); 

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_16_CCITT, INPUT_REFLECT | OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_16_CCITT INPUT_REFLECT | OUTPUT_REFLECT value:0x%08X\n", crcvalue);


	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_32, 0);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_32 normal value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_32, INPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_32 INPUT_REFLECT value:0x%08X\n", crcvalue);

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_32, OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_32 OUTPUT_REFLECT value:0x%08X\n", crcvalue); 

	tls_crypto_crc_init(&ctx, crckey, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_update(&ctx, in, 1024);
	tls_crypto_crc_final(&ctx, &crcvalue);
	printf("CRYPTO_CRC_TYPE_32 INPUT_REFLECT | OUTPUT_REFLECT value:0x%08X\n", crcvalue);

OUT:
	//if(in != NULL)
	//	tls_mem_free(in);
	
	return 0;
}

int md5_hard_demo(void)
{
	psDigestContext_t ctx;
	uint8_t md5hash[16];
	uint8_t *md5in1 = (uint8_t *)"abacdefghgjklmno1234";
	uint8_t *md5in2 = (uint8_t *)"1234567890123456abcd";
	uint8_t md5real[16]={0xD6, 0xEB, 0xD1, 0x1B, 0x0D, 0x42, 0x84, 0xE8, 
					0x52, 0x74, 0xA6, 0xA8, 0x2A, 0x3B, 0x2A, 0x12,};

	tls_crypto_init();	

	tls_crypto_md5_init(&ctx);
	tls_crypto_md5_update(&ctx, md5in1, 20);
	tls_crypto_md5_update(&ctx, md5in2, 20);
	tls_crypto_md5_final(&ctx, md5hash);

	if(memcmp(md5hash, md5real, 16))
	{
		printf("md5 test fail\n");
	}
	else
	{
		printf("md5 test success\n");
	}	

//	printf("md5 hash:");
//	for(int i=0; i<16; i++)
//	{
//		printf("0x%02X, ", md5hash[i]);
//	}
//	printf("\n");
	
	return 0;
}

int sha1_hard_demo(void)
{
	psDigestContext_t ctx;
	uint8_t sha1hash[20];
	uint8_t *sha1in1 = (uint8_t *)"abacdefghgjklmno1234";
	uint8_t *sha1in2 = (uint8_t *)"1234567890123456abcd";
	uint8_t sha1real[20]={0xA9, 0xED, 0x29, 0x56, 0x83, 0x6A, 0x59, 0x22, 0x27, 0x70, 
					0x87, 0x52, 0xDC, 0xB5, 0x1D, 0x2B, 0xBA, 0x93, 0x40, 0xA6,};	

	tls_crypto_init();	

	tls_crypto_sha1_init(&ctx);
	tls_crypto_sha1_update(&ctx, sha1in1, 20);
	tls_crypto_sha1_update(&ctx, sha1in2, 20);
	tls_crypto_sha1_final(&ctx, sha1hash);

	if(memcmp(sha1hash, sha1real, 16))
	{
		printf("sha1 test fail\n");
	}
	else
	{
		printf("sha1 test success\n");
	}	

//	printf("sha1 hash:");
//	for(int i=0; i<20; i++)
//	{
//		printf("0x%02X, ", sha1hash[i]);
//	}
//	printf("\n");	
	return 0;
}


int crypt_hard_demo(void)
{
	RNG_hard_demo();
	rc4_hard_demo();
	aes_hard_demo();
	des_hard_demo();
	des3_hard_demo();
	crc_hard_demo();
	md5_hard_demo();
	sha1_hard_demo();
	return 0;
}

